<template>
  <div class="comment-container">
    <!-- 评论标题 -->
    <div class="comment-header">
      <div class="section-title">
        <icon-message />
        <span>发表评论</span>
      </div>
    </div>

    <!-- 评论输入框 -->
    <div class="comment-input-wrapper">
      <a-comment align="right" class="main-comment-input">
        <template #avatar>
          <a-avatar>
            <img alt="avatar" :src="loginUser.userAvatar" />
          </a-avatar>
        </template>
        <template #actions>
          <div class="comment-input-container">
            <a-textarea
              v-model="comment"
              placeholder="发表你的评论吧~"
              class="comment-input"
              :auto-size="{ minRows: 2, maxRows: 5 }"
            />
            <div class="comment-input-actions">
              <a-button
                key="1"
                type="primary"
                @click="sendComment"
                class="comment-button"
                :loading="commentLoading"
              >
                <template #icon><icon-send /></template>
                发表评论
              </a-button>
            </div>
          </div>
        </template>
      </a-comment>
    </div>

    <!-- 评论列表标题 -->
    <div class="comment-section-header" v-if="questionComment.length > 0">
      <div class="section-title">
        <icon-unordered-list />
        <span>全部评论 ({{ questionComment.length }})</span>
      </div>
    </div>

    <!-- 评论列表 -->
    <div class="comment-list">
      <template v-if="questionComment.length > 0">
        <div
          v-for="(item, index) in questionComment"
          :key="index"
          class="comment-item"
        >
          <a-comment
            :author="item.userName"
            :content="item.content"
            :datetime="moment(item.gmtCreate).format('YYYY-MM-DD HH:mm:ss')"
            class="comment-main"
          >
            <template #actions>
              <div class="comment-actions">
                <!-- 点赞按钮 -->
                <a-button
                  class="action-button"
                  type="text"
                  @click="onLikeChange('comment', index, 0, item.id)"
                >
                  <template #icon>
                    <icon-heart-fill
                      v-if="item.likeListId?.indexOf(loginUser.id) !== -1"
                      class="liked-icon"
                    />
                    <icon-heart v-else />
                  </template>
                  {{ item.likeCount > 0 ? item.likeCount : "点赞" }}
                </a-button>

                <!-- 回复按钮（仅当评论不是自己的时候显示） -->
                <a-button
                  class="action-button"
                  type="text"
                  v-if="loginUser.id !== item.userId"
                  @click="showReplyInput(index, undefined, item)"
                >
                  <template #icon><icon-message /></template>
                  {{ item.commentNum > 0 ? item.commentNum : "回复" }}
                </a-button>

                <!-- 删除按钮（仅当评论是自己的或者是管理员的时候显示） -->
                <a-button
                  class="action-button"
                  type="text"
                  status="danger"
                  v-if="
                    item.userId === loginUser.id ||
                    loginUser.userRole === Access_Enum.Admin
                  "
                  @click="deleteCommentById(item)"
                >
                  <template #icon><icon-delete /></template>
                  删除
                </a-button>
              </div>
            </template>

            <template #avatar>
              <a-avatar>
                <img alt="avatar" :src="item.userAvatar" />
              </a-avatar>
            </template>

            <!-- 一级评论的回复输入框 -->
            <div v-if="item.inputShow" class="reply-input-wrapper">
              <a-avatar class="reply-avatar">
                <img alt="avatar" :src="loginUser.userAvatar" />
              </a-avatar>
              <div class="reply-input-container">
                <a-textarea
                  v-model="replyComment"
                  placeholder="期待你的回复~"
                  class="reply-input"
                  :auto-size="{ minRows: 1, maxRows: 3 }"
                />
                <div class="reply-input-actions">
                  <a-button
                    type="text"
                    @click="showReplyInput(index, undefined, item)"
                    >取消</a-button
                  >
                  <a-button
                    type="primary"
                    @click="sendCommentReply(item)"
                    class="reply-button"
                    :loading="replyLoading"
                  >
                    <template #icon><icon-send /></template>
                    回复
                  </a-button>
                </div>
              </div>
            </div>

            <!-- 二级评论 -->
            <div
              class="replies-container"
              v-if="item.reply && item.reply.length > 0"
            >
              <a-comment
                v-for="(reply, j) in item.reply"
                :key="j"
                :author="reply.userName"
                :content="formattedReplyContent(reply.fromName, reply.content)"
                :datetime="
                  moment(reply.gmtCreate).format('YYYY-MM-DD HH:mm:ss')
                "
                class="reply-comment"
              >
                <template #actions>
                  <div class="comment-actions">
                    <!-- 点赞按钮 -->
                    <a-button
                      class="action-button"
                      type="text"
                      @click="onLikeChange('reply', index, j, reply.id)"
                    >
                      <template #icon>
                        <icon-heart-fill
                          v-if="reply.likeListId?.indexOf(loginUser.id) !== -1"
                          class="liked-icon"
                        />
                        <icon-heart v-else />
                      </template>
                      {{ reply.likeCount > 0 ? reply.likeCount : "点赞" }}
                    </a-button>

                    <!-- 回复按钮 -->
                    <a-button
                      class="action-button"
                      type="text"
                      v-if="loginUser.id !== reply.userId"
                      @click="showReplyInput(index, j, reply)"
                    >
                      <template #icon><icon-message /></template>
                      {{ reply.commentNum > 0 ? reply.commentNum : "回复" }}
                    </a-button>

                    <!-- 删除按钮 -->
                    <a-button
                      class="action-button"
                      type="text"
                      status="danger"
                      v-if="
                        reply.userId === loginUser.id ||
                        loginUser.userRole === Access_Enum.Admin
                      "
                      @click="deleteCommentById(reply)"
                    >
                      <template #icon><icon-delete /></template>
                      删除
                    </a-button>
                  </div>
                </template>

                <template #avatar>
                  <a-avatar>
                    <img alt="avatar" :src="reply.userAvatar" />
                  </a-avatar>
                </template>

                <!-- 二级评论的回复输入框 -->
                <div v-if="reply.inputShow" class="reply-input-wrapper">
                  <a-avatar class="reply-avatar">
                    <img alt="avatar" :src="loginUser.userAvatar" />
                  </a-avatar>
                  <div class="reply-input-container">
                    <a-textarea
                      v-model="replyComment"
                      placeholder="留下您善意的回复吧..."
                      class="reply-input"
                      :auto-size="{ minRows: 1, maxRows: 3 }"
                    />
                    <div class="reply-input-actions">
                      <a-button
                        type="text"
                        @click="showReplyInput(index, j, reply)"
                        >取消</a-button
                      >
                      <a-button
                        type="primary"
                        @click="sendCommentReply(reply)"
                        class="reply-button"
                        :loading="replyLoading"
                      >
                        <template #icon><icon-send /></template>
                        回复
                      </a-button>
                    </div>
                  </div>
                </div>
              </a-comment>
            </div>
          </a-comment>
        </div>
      </template>

      <!-- 没有评论时的提示 -->
      <div v-else class="empty-comment">
        <icon-message :size="64" :stroke-width="1" />
        <p>暂无评论，来发表第一条评论吧！</p>
      </div>
    </div>
  </div>
</template>

<script setup>
import { computed, onMounted, onUnmounted, ref } from "vue";
import {
  IconHeart,
  IconHeartFill,
  IconMessage,
  IconDelete,
  IconSend,
  IconUnorderedList,
} from "@arco-design/web-vue/es/icon";
import { QuestionCommentsControllerService } from "../../generated";
import { useStore } from "vuex";
import moment from "moment";
import message from "@arco-design/web-vue/es/message";
import Access_Enum from "@/access/ACCESS_ENUM";

const store = useStore();
// eslint-disable-next-line no-undef
const Props = defineProps({
  questionId: {
    type: Number,
    default: 0,
  },
});

const loginUser = computed(() => store.state.user.loginUser);

const replyComment = ref("");
const showReply = ref(false);
const comment = ref("");
const questionComment = ref([]);
const lastIndex = ref(0);
const currentComment = ref({
  questionId: Props.questionId,
  userId: loginUser.value.id,
  userName: loginUser.value.userName,
  userAvatar: loginUser.value.userAvatar,
  content: comment.value,
  parentId: -1,
  likeListId: "[]",
  fromId: -1,
  fromName: "",
}); // 当前被点击的评论对象

// 加载状态
const commentLoading = ref(false);
const replyLoading = ref(false);

// 定义轮询间隔时间（单位：毫秒）
const POLLING_INTERVAL = 5000; // 增加间隔以减少服务器负载
let pollingTimer = null; // 用于存储定时器

// 启动轮询
const startPolling = () => {
  pollingTimer = setInterval(async () => {
    const res = await QuestionCommentsControllerService.getCommentListUsingGet(
      Props.questionId
    );
    if (res.code === 0) {
      // 保留原有的 inputShow 状态
      questionComment.value = res.data.map((comment, index) => ({
        ...comment,
        inputShow: questionComment.value[index]?.inputShow || false, // 保留一级评论的 inputShow
        reply: comment.reply.map((reply, j) => ({
          ...reply,
          inputShow: questionComment.value[index]?.reply[j]?.inputShow || false, // 保留二级评论的 inputShow
        })),
      }));
    }
  }, POLLING_INTERVAL);
};
// 停止轮询
const stopPolling = () => {
  clearInterval(pollingTimer);
};

// 在组件挂载时启动轮询
onMounted(() => {
  loadComment(); // 首次加载评论
  startPolling();
});

// 在组件卸载时停止轮询
onUnmounted(() => {
  stopPolling();
});

/**
 * 是否展示输入框
 * @param i
 * @param j
 * @param current
 */
const showReplyInput = (i, j, current) => {
  // 设置当前评论值
  if (current.parentId === "-1" || current.parentId === -1) {
    currentComment.value.parentId = current.id;
  } else {
    currentComment.value.parentId = current.parentId;
  }
  currentComment.value.fromName = current.userName;
  currentComment.value.fromId = current.userId;

  // 输入框可见性的切换逻辑
  if (j !== undefined) {
    // 对于二级评论
    const isCurrentlyShown = questionComment.value[i].reply[j].inputShow;

    // 首先关闭所有输入框
    questionComment.value.forEach((comment, index) => {
      comment.inputShow = false;
      if (comment.reply) {
        comment.reply.forEach((reply) => {
          reply.inputShow = false;
        });
      }
    });

    // 切换当前输入框（只有在之前是关闭状态时才打开）
    questionComment.value[i].reply[j].inputShow = !isCurrentlyShown;
  } else {
    // 对于一级评论
    const isCurrentlyShown = questionComment.value[i].inputShow;

    // 首先关闭所有输入框
    questionComment.value.forEach((comment, index) => {
      comment.inputShow = false;
      if (comment.reply) {
        comment.reply.forEach((reply) => {
          reply.inputShow = false;
        });
      }
    });

    // 切换当前输入框（只有在之前是关闭状态时才打开）
    questionComment.value[i].inputShow = !isCurrentlyShown;
  }

  // 重置回复内容
  if (
    questionComment.value[i].inputShow ||
    (j !== undefined && questionComment.value[i].reply[j].inputShow)
  ) {
    replyComment.value = "";
  }
};

/**
 * 深拷贝
 * @param targetObj
 * @returns {*}
 */
const copyObject = (targetObj) => {
  let comment = { ...targetObj };
  // 转换为以,号分割的字符串 [因为后端采用的是字符串进行存储]
  comment.likeListId = "[" + comment.likeListId.join(",") + "]";
  // 删除掉该属性，不然后端接收会报错
  delete comment.reply;
  return comment;
};

/**
 * 删除评论
 * @param current
 * @returns {Promise<void>}
 */
const deleteCommentById = async (current) => {
  try {
    let comment = copyObject(current);
    const res = await QuestionCommentsControllerService.deleteQuestionUsingPost(
      comment
    );
    if (res.code === 0) {
      message.success("删除成功");
      // 重新加载评论数据
      await loadComment();
    } else {
      message.error("删除失败：" + res.message);
    }
  } catch (error) {
    message.error("操作出错：" + error);
  }
};

/**
 * 加载评论
 * @returns {Promise<void>}
 */
const loadComment = async () => {
  try {
    const res = await QuestionCommentsControllerService.getCommentListUsingGet(
      Props.questionId
    );
    if (res.code === 0 && res.data) {
      questionComment.value = (Array.isArray(res.data) ? res.data : []).map(
        (comment, index) => ({
          ...comment,
          inputShow: questionComment.value[index]?.inputShow || false, // 保留一级评论的 inputShow
          reply: Array.isArray(comment.reply)
            ? comment.reply.map((reply, j) => ({
                ...reply,
                inputShow:
                  questionComment.value[index]?.reply[j]?.inputShow || false, // 保留二级评论的 inputShow
              }))
            : [], // 如果 comment.reply 不是数组，设置为空数组
        })
      );
    } else {
      questionComment.value = []; // 如果 res.data 不存在，设置为空数组
    }
  } catch (error) {
    message.error("加载评论失败：" + error);
    questionComment.value = [];
  }
};

/**
 * 点赞或取消点赞
 * @param {string} type 评论类型 (comment 或 reply)
 * @param {number} i 评论索引
 * @param {number} j 回复索引
 * @param {number} id 评论ID
 * @returns {Promise<void>}
 */
const onLikeChange = async (type, i, j, id) => {
  try {
    const commentObje =
      type === "comment"
        ? questionComment.value[i]
        : questionComment.value[i].reply[j];
    let list = commentObje.likeListId;

    if (list.length === 0 || list.indexOf(loginUser.value.id) === -1) {
      // 在已经点赞的列表中未找到 userId
      commentObje.isLike = true;
      commentObje.likeCount += 1;
      commentObje.likeListId.push(loginUser.value.id);

      // 将对象复制一份并且去除掉 reply 属性，避免后台接收数据出现异常
      let comment = copyObject(commentObje);
      // 发送请求到后台修改点赞数量
      const res =
        await QuestionCommentsControllerService.updateQuestionCommentUsingPost(
          comment
        );
      if (res.code === 0) {
        await loadComment();
      }
    } else {
      const index = list.indexOf(loginUser.value.id);
      commentObje.isLike = false;
      commentObje.likeCount -= 1;
      commentObje.likeListId.splice(index, 1);

      // 将对象复制一份并且去除掉 reply 属性，避免后台接收数据出现异常
      let comment = copyObject(commentObje);
      // 发送请求到后台修改点赞数量
      const res =
        await QuestionCommentsControllerService.updateQuestionCommentUsingPost(
          comment
        );
      if (res.code === 0) {
        await loadComment();
      }
    }
  } catch (error) {
    message.error("操作失败：" + error);
  }
};

/**
 * 格式化回复内容，添加样式
 * @param {string} userName 被回复的用户名
 * @param {string} content 回复的内容
 * @returns {string} 格式化后的文本内容
 */
const formattedReplyContent = (userName, content) => {
  return `回复 ${userName} : ${content}`;
};

/**
 * 发送评论
 * @returns {Promise<void>}
 */
const sendComment = async () => {
  if (comment.value.trim() === "") {
    message.warning("评论不能为空");
    return;
  }

  commentLoading.value = true;
  try {
    // 重置currentComment为一级评论状态
    currentComment.value = {
      questionId: Props.questionId,
      userId: loginUser.value.id,
      userName: loginUser.value.userName,
      userAvatar: loginUser.value.userAvatar,
      content: comment.value,
      parentId: -1, // 确保是一级评论
      likeListId: "[]",
      fromId: -1,
      fromName: "",
    };

    const commentAddRequest = {
      currentComment: currentComment.value,
    };
    const res =
      await QuestionCommentsControllerService.addQuestionCommentWrapUsingPost(
        commentAddRequest
      );
    if (res.code === 0) {
      comment.value = "";
      await loadComment();
      message.success("评论成功");
    } else {
      message.error("评论失败：" + res.message);
    }
  } catch (error) {
    message.error("发送评论失败：" + error);
  } finally {
    commentLoading.value = false;
  }
};

/**
 * 发送回复
 * @param {object} current 当前评论对象
 * @returns {Promise<void>}
 */
const sendCommentReply = async (current) => {
  if (!replyComment.value.trim()) {
    message.warning("回复不能为空");
    return;
  }

  // 确保 current 是有效的对象
  if (!current || !current.id) {
    message.error("无效的评论对象");
    return;
  }

  replyLoading.value = true;
  try {
    // 回复内容对象
    currentComment.value.content = replyComment.value;
    // 更新当前被点击的评论对象的回复条数
    current.commentNum += 1;

    let parent = { ...current };
    parent.likeListId = "[" + parent.likeListId.join(",") + "]";
    delete parent.reply; // 删除属性，否则后端接收数据出现异常

    const commentAddRequest = {
      currentComment: currentComment.value,
      parentComment: parent,
    };

    const res =
      await QuestionCommentsControllerService.addQuestionCommentWrapUsingPost(
        commentAddRequest
      );

    if (res.code === 0) {
      message.success("回复成功");
      await loadComment();
      // 手动关闭输入框
      if (current.parentId === "-1" || current.parentId === -1) {
        // 一级评论
        questionComment.value.forEach((comment) => (comment.inputShow = false));
      } else {
        // 二级评论
        questionComment.value.forEach((comment) => {
          if (comment.reply) {
            comment.reply.forEach((reply) => (reply.inputShow = false));
          }
        });
      }

      // 重置回复内容
      replyComment.value = "";
    } else {
      message.error("回复失败：" + res.message);
    }
  } catch (error) {
    message.error("发送回复失败：" + error);
  } finally {
    replyLoading.value = false;
  }
};
</script>

<style scoped>
.comment-container {
  width: 100%;
  padding: 8px 0;
}

.comment-header,
.comment-section-header {
  margin-bottom: 16px;
}

.section-title {
  display: flex;
  align-items: center;
  gap: 8px;
  color: #165dff;
  font-weight: 500;
  font-size: 16px;
}

/* 评论输入区域 */
.comment-input-wrapper {
  margin-bottom: 24px;
  background-color: #f7f8fa;
  border-radius: 8px;
  padding: 16px;
}

.main-comment-input {
  width: 100%;
}

.comment-input-container {
  display: flex;
  flex-direction: column;
  width: 100%;
  gap: 12px;
}

.comment-input {
  width: 100%;
  resize: none;
  border-radius: 4px;
}

.comment-input-actions {
  display: flex;
  justify-content: flex-end;
}

.comment-button {
  align-self: flex-end;
}

/* 评论列表 */
.comment-list {
  margin-top: 16px;
}

.comment-item {
  margin-bottom: 16px;
  padding: 16px;
  border-radius: 8px;
  background-color: #f7f8fa;
  transition: background-color 0.3s;
}

.comment-item:hover {
  background-color: #edf0f5;
}

.comment-main {
  width: 100%;
}

/* 评论操作按钮 */
.comment-actions {
  display: flex;
  gap: 16px;
}

.action-button {
  padding: 0;
  height: auto;
}

.liked-icon {
  color: #f53f3f;
}

/* 回复区域 */
.replies-container {
  margin-top: 16px;
  margin-left: 40px;
  border-left: 2px solid #e5e6eb;
  padding-left: 16px;
}

.reply-comment {
  margin-bottom: 12px;
  padding: 12px;
  background-color: #ffffff;
  border-radius: 6px;
}

/* 回复输入框 */
.reply-input-wrapper {
  display: flex;
  gap: 12px;
  margin-top: 12px;
  padding: 12px;
  background-color: #ffffff;
  border-radius: 6px;
}

.reply-avatar {
  flex-shrink: 0;
}

.reply-input-container {
  display: flex;
  flex-direction: column;
  flex-grow: 1;
  gap: 8px;
}

.reply-input {
  width: 100%;
  resize: none;
  border-radius: 4px;
}

.reply-input-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}

/* 空评论状态 */
.empty-comment {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 40px 0;
  color: #86909c;
  background-color: #f7f8fa;
  border-radius: 8px;
  text-align: center;
}

.empty-comment p {
  margin-top: 12px;
  font-size: 14px;
}

:deep(.arco-comment-content) {
  background-color: transparent;
  padding: 8px 0;
}

:deep(.arco-comment-author) {
  font-weight: 500;
  font-size: 15px;
}

:deep(.arco-comment-datetime) {
  color: #86909c;
  font-size: 12px;
}

:deep(.arco-comment-content-detail) {
  color: #333;
  font-size: 14px;
  line-height: 1.6;
}
</style>
